package com.example.everying.utils;

import com.example.everying.model.job.ScheduleJob;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Date;
import java.util.Calendar;
import java.util.Set;

/**
 * @program: everything
 * @description: 定时任务工具类
 * @author: zw
 * @create: 2025-07-09 09:51
 **/
@Slf4j
@Component
public class QuartzUtils {
    @Resource
    private Scheduler scheduler;

    /**
     * 创建定时任务
     */
    public void createJob(ScheduleJob job) throws SchedulerException {
        // 判断任务是否已删除（isDelete=1），如果已删除则不创建定时任务
        if (job.getIsDelete() == 1) {
            // 添加日志记录，方便排查
            log.info("任务[{}({})]已被标记为删除，不创建定时任务", job.getJobName(), job.getJobId());
            return;
        }
        // 构建JobDetail
        JobDetail jobDetail = JobBuilder.newJob(getJobClass())
                .withIdentity(job.getJobName(), job.getJobId())
                .withDescription(job.getDescription())
                .storeDurably(false) // 任务完成后不持久化
                .build();
        // 传递参数
        jobDetail.getJobDataMap().put("jobParam", job);
        // 构建Trigger
        CronTrigger trigger = TriggerBuilder.newTrigger()
                .withIdentity(job.getJobName() + "_trigger", job.getJobId()) // 触发器唯一标识
                .withSchedule(CronScheduleBuilder.cronSchedule(job.getCronExpression())
                        .withMisfireHandlingInstructionDoNothing()) // 错过执行时不处理
                .build();
        // 注册任务和触发器
        scheduler.scheduleJob(jobDetail, trigger);
    }
    /**
     * 将Date转换为完整的Cron表达式（秒 分 时 日 月 周 年）
     * @param executeTime 执行时间
     * @return 完整的Cron表达式字符串
     */
    public String generateCronExpression(Date executeTime) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(executeTime);

        // 获取各个时间字段的值
        int second = cal.get(Calendar.SECOND);
        int minute = cal.get(Calendar.MINUTE);
        int hour = cal.get(Calendar.HOUR_OF_DAY);
        int day = cal.get(Calendar.DAY_OF_MONTH);
        int month = cal.get(Calendar.MONTH) + 1; // 月份从0开始，需要+1
        int year = cal.get(Calendar.YEAR);

        // 周字段使用?表示不指定，避免与日字段冲突
        return String.format("%d %d %d %d %d ? %d",
                second, minute, hour, day, month, year);
    }
    /**
     * 删除指定任务（供任务执行后调用）
     */
    public void deleteJob(String jobName, String jobId) throws SchedulerException {
        JobKey jobKey = new JobKey(jobName, jobId);
        if (scheduler.checkExists(jobKey)) {
            boolean result = scheduler.deleteJob(jobKey);
            log.info("任务[{}({})]删除状态：{}", jobName, jobId, result ? "成功" : "失败");
        } else {
            log.warn("任务[{}({})]不存在，无需删除", jobName, jobId);
        }
    }
    /**
     * 查询所有任务（用于清理）
     */
    public Set<JobKey> listAllJobs() throws SchedulerException {
        return scheduler.getJobKeys(GroupMatcher.anyJobGroup());
    }

    // 获取任务类（根据实际业务调整）
    private Class<? extends Job> getJobClass() {
        return MyDynamicJob.class;
    }

    // 任务类示例（需实现 Job 接口并注入 Scheduler）
    @Component
    public static class MyDynamicJob implements Job {
        @Autowired
        private QuartzUtils quartzUtils; // 注入工具类

        @Override
        public void execute(JobExecutionContext context) throws JobExecutionException {
            try {
                // 1. 获取任务参数
                JobDataMap dataMap = context.getMergedJobDataMap();
                ScheduleJob job = (ScheduleJob) dataMap.get("jobParam");
                log.info("执行任务：{}({})，内容：{}", job.getJobName(), job.getJobId(), job.getDescription());

                // 2. 执行完业务逻辑后，删除任务
                quartzUtils.deleteJob(job.getJobName(), job.getJobId());
            } catch (SchedulerException e) {
                log.error("任务执行失败", e);
                throw new JobExecutionException(e);
            }
        }
    }
}
